from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
from datetime import datetime, date


class HostelStudent(models.Model):
    _name = 'hostel.student'
    _description = 'Hostel Student'
    _rec_name = 'name'
    _inherit = ['mail.thread', 'mail.activity.mixin']

    name = fields.Char(string="Student Name", required=True)
    gender = fields.Selection([
        ('male', 'Male'),
        ('female', 'Female'),
        ('other', 'Other')
    ], string="Gender", required=True, tracking=True)
    active = fields.Boolean(string="Active", default=True, tracking=True)
    room_id = fields.Many2one('hostel.room', string="Room", tracking=True)
    class_id = fields.Char(string="Class", required=True, tracking=True)
    
    # 条码扫描按钮字段
    barcode_scan_button = fields.Boolean(string="扫描条码", default=False)
    
    # 入住日期相关字段
    check_in_date = fields.Date(string="Check-in Date", required=True, 
                               default=fields.Date.context_today,
                               help="Date when student checked into the room", tracking=True)
    check_out_date = fields.Date(string="Check-out Date", 
                                help="Date when student checked out of the room", tracking=True)
    stay_duration = fields.Integer(string="Stay Duration (Days)", 
                                  compute='_compute_stay_duration', store=True,
                                  help="Number of days the student stayed in the room")
    
    # 状态字段
    status = fields.Selection([
        ('draft', 'Draft'),
        ('reservation', 'Reservation'),
        ('pending', 'Pending'),
        ('paid', 'Paid'),
        ('discharge', 'Discharge'),
        ('cancel', 'Cancel')
    ], string="Status", default='draft', required=True,
       help="Current status of the student", tracking=True)
    
    # 计算字段
    hostel_id = fields.Many2one('hostel.hostel', string="Hostel", 
                               related='room_id.hostel_id', store=True, readonly=True)
    
    @api.onchange('barcode_scan_button')
    def _onchange_barcode_scan_button(self):
        """当点击扫描按钮时触发（不会保存表单）"""
        if self.barcode_scan_button:
            # 重置按钮状态
            self.barcode_scan_button = False
            
            # 返回客户端动作
            return {
                'type': 'ir.actions.client',
                'tag': 'barcode_scanner_direct_action',
                'params': {
                    'model': 'hostel.student',
                    'res_id': self.id if self.id else False,
                }
            }
    
    @api.depends('check_in_date', 'check_out_date')
    def _compute_stay_duration(self):
        for record in self:
            if record.check_in_date and record.check_out_date:
                # 计算两个日期之间的天数差
                delta = record.check_out_date - record.check_in_date
                record.stay_duration = delta.days
            elif record.check_in_date:
                # 如果只有入住日期，计算从入住日期到今天的天数
                today = fields.Date.context_today(self)
                delta = today - record.check_in_date
                record.stay_duration = delta.days
            else:
                record.stay_duration = 0
    
    @api.model
    def name_get(self):
        result = []
        for record in self:
            name = f"{record.name} ({record.class_id})"
            result.append((record.id, name))
        return result
    
    def action_create_room(self):
        """为状态为paid的学生创建房间"""
        if self.status != 'paid':
            raise ValidationError(_('Only students with paid status can create rooms'))
        
        # 创建房间
        room_vals = {
            'name': self.name,
            'room_no': self.name,
            'floor_no': 1,
            'hostel_id': self.hostel_id.id,
            'student_per_room': 1,
            'rent_amount': 0.0,
            'state': 'available'
        }
        
        room = self.env['hostel.room'].sudo().create(room_vals)
        
        # 更新学生的房间
        self.sudo().room_id = room.id
        
        return {
            'type': 'ir.actions.act_window',
            'name': 'Created Room',
            'res_model': 'hostel.room',
            'res_id': room.id,
            'view_mode': 'form',
            'target': 'current',
        }
    
    def remove_from_room(self):
        """移除学生与房间的关联"""
        self.sudo().room_id = False
        return True
    
    @api.model
    def create_temp_for_scanner(self):
        """为扫描器创建临时记录"""
        temp_vals = {
            'name': 'Temp_' + str(fields.datetime.now().strftime('%Y%m%d_%H%M%S')),
            'gender': 'other',
            'class_id': 'Temp',
            'active': True,
            'status': 'draft'
        }
        temp_record = self.env['hostel.student'].sudo().create(temp_vals)
        return temp_record.id
    
    def open_barcode_scanner(self):
        """打开条码扫描器"""
        # 检查是否跳过验证
        skip_validation = self.env.context.get('skip_validation', False)
        
        # 检查是否是已有记录
        if self.id:
            # 已有记录，直接使用现有ID
            res_id = self.id
            is_new_record = False
        else:
            # 新记录，创建临时记录来避免验证问题
            temp_vals = {
                'name': 'Temp_' + str(fields.datetime.now().strftime('%Y%m%d_%H%M%S')),
                'gender': 'other',
                'class_id': 'Temp',
                'active': True,
                'status': 'draft'
            }
            
            # 如果有hostel_id，也设置上
            if hasattr(self, 'hostel_id') and self.hostel_id:
                temp_vals['hostel_id'] = self.hostel_id.id
            
            # 使用sudo()跳过权限检查
            temp_record = self.env['hostel.student'].sudo().create(temp_vals)
            res_id = temp_record.id
            is_new_record = True
            
        return {
            'type': 'ir.actions.client',
            'tag': 'barcode_scanner_action',
            'params': {
                'model': 'hostel.student',
                'res_id': res_id,
                'is_new_record': is_new_record,
                'skip_validation': skip_validation,
            }
        }
    
    def open_barcode_scanner_direct(self):
        """直接打开条码扫描器（不触发表单保存）"""
        # 这个方法直接返回客户端动作，不进行任何数据库操作
        return {
            'type': 'ir.actions.client',
            'tag': 'barcode_scanner_direct_action',
            'params': {}
        }
    
    def send_room_assignment_email(self):
        """发送房间分配通知邮件给关注者"""
        import logging
        _logger = logging.getLogger(__name__)
        
        self.ensure_one()
        
        if not self.room_id:
            raise ValidationError(_('Student has not been assigned to a room yet!'))
        
        # 详细日志：学生信息
        _logger.info("=" * 80)
        _logger.info("🔍 开始发送邮件 - 学生信息：")
        _logger.info(f"  学生 ID: {self.id}")
        _logger.info(f"  学生姓名: {self.name}")
        _logger.info(f"  房间: {self.room_id.room_no if self.room_id else 'None'}")
        _logger.info(f"  创建用户: {self.create_uid.name} ({self.create_uid.email})")
        
        # 详细日志：关注者信息
        _logger.info("👥 关注者信息：")
        _logger.info(f"  message_follower_ids: {self.message_follower_ids}")
        _logger.info(f"  message_follower_ids.ids: {self.message_follower_ids.ids}")
        _logger.info(f"  message_partner_ids: {self.message_partner_ids}")
        _logger.info(f"  message_partner_ids.ids: {self.message_partner_ids.ids}")
        
        # 详细日志：关注者邮箱
        follower_emails = []
        if self.message_partner_ids:
            _logger.info("📧 关注者邮箱列表：")
            for partner in self.message_partner_ids:
                _logger.info(f"    - Partner ID: {partner.id}, 名称: {partner.name}, 邮箱: {partner.email}")
                if partner.email:
                    follower_emails.append(partner.email)
        else:
            _logger.warning("⚠️  没有关注者！")
        
        # 获取邮件模板
        template = self.env.ref('my_hostel.email_template_room_assignment', raise_if_not_found=False)
        
        if not template:
            raise ValidationError(_('Email template not found! Please contact administrator.'))
        
        # 渲染邮件模板以获取实际的收发件人
        try:
            email_to = template._render_field('email_to', [self.id])[self.id] if template.email_to else None
            email_from = template._render_field('email_from', [self.id])[self.id] if template.email_from else None
            partner_to = template._render_field('partner_to', [self.id])[self.id] if template.partner_to else None
        except Exception as e:
            _logger.error(f"渲染模板字段失败: {str(e)}")
            email_to = "渲染失败"
            email_from = "渲染失败"
            partner_to = "渲染失败"
        
        # 详细日志：邮件模板信息
        _logger.info("📧 邮件模板信息：")
        _logger.info(f"  模板 ID: {template.id}")
        _logger.info(f"  模板名称: {template.name}")
        _logger.info(f"  email_to (模板): {template.email_to}")
        _logger.info(f"  email_to (渲染后): {email_to}")
        _logger.info(f"  email_from (模板): {template.email_from}")
        _logger.info(f"  email_from (渲染后): {email_from}")
        _logger.info(f"  partner_to (模板): {template.partner_to}")
        _logger.info(f"  partner_to (渲染后): {partner_to}")
        
        # 获取系统邮件配置
        IrMailServer = self.env['ir.mail_server']
        mail_server = IrMailServer.sudo().search([], limit=1)
        if mail_server:
            _logger.info("📮 邮件服务器配置：")
            _logger.info(f"  服务器名称: {mail_server.name}")
            _logger.info(f"  SMTP 服务器: {mail_server.smtp_host}")
            _logger.info(f"  SMTP 用户: {mail_server.smtp_user}")
            _logger.info(f"  发件人(FROM)过滤: {mail_server.from_filter}")
        
        # 获取系统参数
        bounce_email = self.env['ir.config_parameter'].sudo().get_param('mail.bounce.alias', 'bounce')
        catchall_domain = self.env['ir.config_parameter'].sudo().get_param('mail.catchall.domain', '')
        _logger.info("⚙️  系统邮件参数：")
        _logger.info(f"  Bounce alias: {bounce_email}")
        _logger.info(f"  Catchall domain: {catchall_domain}")
        _logger.info(f"  完整 bounce 地址: {bounce_email}@{catchall_domain}")
        
        # 准备在浏览器显示的调试信息
        debug_info = {
            'student': {
                'id': self.id,
                'name': self.name,
                'create_user': self.create_uid.name,
                'create_email': self.create_uid.email,
            },
            'followers': [
                {'id': p.id, 'name': p.name, 'email': p.email}
                for p in self.message_partner_ids
            ],
            'template': {
                'id': template.id,
                'name': template.name,
                'email_to_template': template.email_to,
                'email_to_rendered': email_to,
                'email_from_template': template.email_from,
                'email_from_rendered': email_from,
                'partner_to_template': template.partner_to,
                'partner_to_rendered': partner_to,
            },
            'mail_server': {
                'name': mail_server.name if mail_server else None,
                'smtp_host': mail_server.smtp_host if mail_server else None,
                'smtp_user': mail_server.smtp_user if mail_server else None,
            } if mail_server else None,
            'system_params': {
                'bounce_email': bounce_email,
                'catchall_domain': catchall_domain,
                'full_bounce': f"{bounce_email}@{catchall_domain}",
            }
        }
        
        # 发送邮件给所有关注者
        try:
            _logger.info("📤 开始发送邮件...")
            
            # 方案：使用模板的 send_mail 方法，但循环为每个关注者发送
            sent_count = 0
            
            for partner in self.message_partner_ids:
                if partner.email:
                    try:
                        # 使用 with_context 临时修改收件人
                        ctx = {
                            'default_email_to': partner.email,
                            'default_email_from': 'yan.gao@ccwin-in.com',
                        }
                        
                        # 使用模板的 send_mail 方法（会自动渲染）
                        mail_id = template.with_context(ctx).send_mail(
                            self.id,
                            force_send=False,  # 先不发送，稍后统一发送
                            email_values={
                                'email_to': partner.email,
                                'email_from': 'yan.gao@ccwin-in.com',
                            }
                        )
                        
                        # 发送邮件
                        if mail_id:
                            mail = self.env['mail.mail'].sudo().browse(mail_id)
                            mail.send()
                            sent_count += 1
                            _logger.info(f"  ✅ 已发送给: {partner.name} ({partner.email})")
                            
                            # 检查邮件内容是否正确渲染
                            if mail.body_html:
                                if '{{' in mail.body_html or '{%' in mail.body_html:
                                    _logger.warning(f"  ⚠️  邮件内容中仍包含未渲染的模板语法")
                                else:
                                    _logger.info(f"  ✅ 邮件内容已完全渲染")
                    except Exception as e:
                        _logger.error(f"  ❌ 发送给 {partner.email} 失败: {str(e)}")
                        import traceback
                        _logger.error(traceback.format_exc())
            
            _logger.info(f"✅ 邮件发送完成！成功发送 {sent_count}/{len(self.message_partner_ids)} 封")
            _logger.info("=" * 80)
            
            # 在chatter中记录邮件发送
            self.message_post(
                body=_('房间分配通知邮件已发送给关注者。房间：%s，宿舍：%s') % (
                    self.room_id.room_no, 
                    self.hostel_id.name if self.hostel_id else '未分配'
                ),
                subject=_('邮件发送通知'),
                message_type='notification',
            )
            
            return {
                'type': 'ir.actions.client',
                'tag': 'display_notification',
                'params': {
                    'title': _('邮件发送成功'),
                    'message': _('房间分配通知邮件已发送。请查看浏览器 Console 了解详情。'),
                    'type': 'success',
                    'sticky': False,
                },
                'context': {
                    'debug_info': debug_info,  # 传递调试信息到前端
                }
            }
        except Exception as e:
            _logger.error(f"❌ 邮件发送失败: {str(e)}")
            _logger.error("=" * 80)
            import traceback
            _logger.error(traceback.format_exc())
            
            # 返回详细的错误信息
            return {
                'type': 'ir.actions.client',
                'tag': 'display_notification',
                'params': {
                    'title': _('邮件发送失败'),
                    'message': _('错误: %s\n请查看浏览器 Console 和服务器日志了解详情。') % str(e),
                    'type': 'danger',
                    'sticky': True,
                },
                'context': {
                    'debug_info': debug_info,
                    'error': str(e),
                }
            }
    
    @api.model_create_multi
    def create(self, vals_list):
        """重写create方法，在房间分配时自动发送邮件"""
        records = super(HostelStudent, self).create(vals_list)
        
        for record in records:
            if record.room_id:
                # 在chatter中记录房间分配
                record.message_post(
                    body=_('学生已被分配到房间 %s') % record.room_id.room_no,
                    subject=_('房间分配'),
                    message_type='notification',
                )
        
        return records
    
    def write(self, vals):
        """重写write方法，追踪房间分配变更"""
        # 记录旧的room_id
        old_room_ids = {record.id: record.room_id for record in self}
        
        result = super(HostelStudent, self).write(vals)
        
        # 检查room_id是否发生变化
        if 'room_id' in vals:
            for record in self:
                old_room = old_room_ids.get(record.id)
                new_room = record.room_id
                
                # 如果房间发生了变化
                if old_room != new_room:
                    if new_room and not old_room:
                        # 新分配房间
                        record.message_post(
                            body=_('学生已被分配到房间 %s，宿舍：%s') % (
                                new_room.room_no,
                                new_room.hostel_id.name if new_room.hostel_id else '未分配'
                            ),
                            subject=_('房间分配'),
                            message_type='notification',
                        )
                    elif new_room and old_room:
                        # 更换房间
                        record.message_post(
                            body=_('学生房间已更换，原房间：%s，新房间：%s') % (
                                old_room.room_no,
                                new_room.room_no
                            ),
                            subject=_('房间变更'),
                            message_type='notification',
                        )
                    elif not new_room and old_room:
                        # 移除房间
                        record.message_post(
                            body=_('学生已从房间 %s 移除') % old_room.room_no,
                            subject=_('移除房间'),
                            message_type='notification',
                        )
        
        return result
